package net.helix.ui.panels.timeline;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JSplitPane;

import net.helix.element.Element_Camera;
import net.helix.element.ViewNodeElement;
import net.helix.engine.Engine;
import net.helix.engine.timeline.layer.TimelineLayer;
import net.helix.engine.timeline.layer.TimelineLayerButton;
import net.helix.engine.timeline.layer.TimelineLayerType;
import net.helix.engine.viewPath.ViewPath;
import net.helix.ui.UIImages;
import net.helix.ui.panels.JImageButton;

/**
 * The timeline pane which contains the timeline with the selectable layers on the left side (called
 * names) and the frames on the right side (called frames).
 * @author Runouw
 *
 */
public class TimelinePane extends JPanel  {
	private static final long serialVersionUID = 1L;
	
	private TimelineNamesPane names;
	private TimelineFramesPane frames;
	
	private JScrollBar hScroll;
	private JScrollBar vScroll;
	private JPanel hScrollParent;
	private JPanel hScrollBox;
	
	private Engine engine;
	
	private JPopupMenu buttonMenu;
	private JImageButton makePopupButton;
	/**
	 * Create the timeline pane.
	 * @param engine
	 */
	public TimelinePane(Engine engine){
		super();
		this.engine = engine;
		
		this.setLayout(new BorderLayout());
		
		MouseWheelListener mouseListen = new MouseWheelListener(){

			@Override
			public void mouseWheelMoved(MouseWheelEvent arg0) {
				System.out.println(arg0.getWheelRotation());
				vScroll.setValue(vScroll.getValue() + (int)(arg0.getWheelRotation()*10));
				
			}
		};
		
		
		
		buttonMenu = new JPopupMenu();
		buttonMenu.add("New 2D Layer");
		buttonMenu.add("New 3D Layer");
		buttonMenu.add("New Folder");
		//this.add(buttonMenu);
		
		makePopupButton = new JImageButton(UIImages.popupGeneratorIcon);
		makePopupButton.setPreferredSize(new Dimension(15, 15));
		makePopupButton.setSize(new Dimension(15, 15));
		makePopupButton.setToolTipText("Create new...");
		
		makePopupButton.addMouseListener(new MouseListener(){
			@Override
			public void mouseClicked(MouseEvent e) {
				buttonMenu.show(makePopupButton, 0, makePopupButton.getHeight());
			}
			@Override
			public void mouseEntered(MouseEvent e) {
				
			}
			@Override
			public void mouseExited(MouseEvent e) {
				
			}
			@Override
			public void mousePressed(MouseEvent e) {
				
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				
			}
		});
		
		frames = new TimelineFramesPane(engine, this);
		names = new TimelineNamesPane(engine, this);
		
		JPanel namePane = new JPanel();
		
		JPanel timelineTools = new JPanel();
		
		JPanel framesPane = new JPanel();
		
		hScroll = new JScrollBar(JScrollBar.HORIZONTAL);
		vScroll = new JScrollBar(JScrollBar.VERTICAL);
		
		vScroll.setUnitIncrement(10);
		hScroll.setUnitIncrement(5);
		
		hScroll.addAdjustmentListener(new AdjustmentListener(){

			@Override
			public void adjustmentValueChanged(AdjustmentEvent arg0) {
				frames.scrollX = hScroll.getValue();
				frames.repaint();
			}
			
		});
		
		vScroll.addAdjustmentListener(new AdjustmentListener(){
			@Override
			public void adjustmentValueChanged(AdjustmentEvent arg0) {
				frames.scrollY = vScroll.getValue();
				frames.repaint();
				
				names.scrollY = vScroll.getValue();
				names.repaint();
			}
			
		});
		
		namePane.setLayout(new BorderLayout());
		framesPane.setLayout(new BorderLayout());
		
		namePane.add(timelineTools);
		timelineTools.setLayout(new BorderLayout());
		JLabel label = new JLabel("Timeline");
		timelineTools.add(label, BorderLayout.LINE_START);
		
		JPanel popupButtonContainer = new JPanel();
		
		//timelineTools.setPreferredSize(new Dimension(17, 17));
		//timelineTools.setSize(new Dimension(17, 17));
		//timelineTools.add(popupButtonContainer);
		timelineTools.add(popupButtonContainer, BorderLayout.LINE_END);
		popupButtonContainer.setLayout(new FlowLayout());
		popupButtonContainer.add(makePopupButton);
		
		namePane.add(names, BorderLayout.CENTER);
		namePane.add(timelineTools, BorderLayout.PAGE_END);
		
		framesPane.add(frames, BorderLayout.CENTER);
		
		hScrollParent = new JPanel();
		hScrollParent.setLayout(new BorderLayout());
		hScrollParent.add(hScroll, BorderLayout.CENTER);
		
		hScrollBox = new JPanel();
		hScrollBox.setPreferredSize(new Dimension(17, 17));
		hScrollParent.add(hScrollBox, BorderLayout.LINE_END);
		
		framesPane.add(hScrollParent, BorderLayout.PAGE_END);
		framesPane.add(vScroll, BorderLayout.LINE_END);
		
		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, namePane, framesPane);
		splitPane.setDividerLocation(150);
		splitPane.setContinuousLayout(true);
		
		splitPane.addPropertyChangeListener(new PropertyChangeListener(){

			@Override
			public void propertyChange(PropertyChangeEvent arg0) {
				UpdateTimelineScrollbars();
				
			}
			
		});
		
		UpdateTimeline();
		
		this.add(splitPane, BorderLayout.CENTER);
		
		//this.add(names, BorderLayout.LINE_START);
		//this.add(frames, BorderLayout.CENTER);
		
		//JLabel label = new JLabel("Timeline");
		//this.add(label, BorderLayout.PAGE_END);
		
		this.addMouseWheelListener(mouseListen);
		names.addMouseWheelListener(mouseListen);
		frames.addMouseWheelListener(mouseListen);
		
	}
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		UpdateTimelineScrollbars();
	}
	/**
	 * Call this whenever the timeline changes the number of layers or frames...
	 */
	public void UpdateTimeline(){
		frames.repaint();
		names.repaint();
		
		UpdateTimelineScrollbars();
	}
	public void UpdateTimelineScrollbars(){
		if(engine.getCurrentSelectedTimeline() == null) return;
		
		int maxy = 0;
		
		getListOfLayers();
		if(listOfLayers != null){
			maxy = listOfLayers.size();
		}
		
		int vMax = maxy*20 - frames.getHeight()*3/4;
		int vMaxExtent = frames.getHeight();
		
		int maxx = 0;
		int l = engine.getCurrentSelectedTimeline().layers.size();
		for(int i=0;i<l;i++){
			int n2 = engine.getCurrentSelectedTimeline().layers.get(i).frames.size();
			if(n2 > maxx){
				maxx = n2;
			}
		}
		
		int hMax = maxx*9 - frames.getWidth()*3/4;
		int hMaxExtent = frames.getWidth();
		
		vScroll.setValues(vScroll.getValue(), vMaxExtent, 0, vMax+vMaxExtent);
		hScroll.setValues(hScroll.getValue(), hMaxExtent, 0, hMax+hMaxExtent);
		
		boolean vScrollVisible = true;
		boolean hScrollParentVisible = true;
		boolean hScrollBoxVisible = true;
		
		if(vMax <= 0) {
			vScrollVisible = false;
			hScrollBoxVisible = false;
			
			vScroll.setVisible(false);
			hScrollBox.setVisible(false);
		};
		if(hMax <= 0) {
			hScrollParentVisible = false;
			hScrollBoxVisible = false;
			
			hScrollParent.setVisible(false);
			hScrollBox.setVisible(false);
			//hScroll.setVisible(false);
		}
		
		if(vScroll.isVisible() != vScrollVisible) vScroll.setVisible(vScrollVisible);
		if(hScrollParent.isVisible() != hScrollParentVisible) hScrollParent.setVisible(hScrollParentVisible);
		if(hScrollBox.isVisible() != hScrollBoxVisible) hScrollBox.setVisible(hScrollBoxVisible);
		
		
	}
	public ArrayList<TimelineLayerButton> listOfLayers  = null;
	public void reloadLayersList(){
		listOfLayers = null;
	}
	/**
	 * @return Returns a list of the current layers that should be displayed in the
	 * timeline.
	 */
	public ArrayList<TimelineLayerButton> getListOfLayers(){
		if(listOfLayers == null){
			// recalculate list
			listOfLayers = new ArrayList<TimelineLayerButton>();
			
			
			
			
			boolean defaultShowAllLayers = true;
			
			
			
			if(engine.getCurrentSelectedView() != null){
				ViewPath path = engine.getCurrentSelectedView().getViewPath();
				if(path != null){
					ViewNodeElement element = path.getRoot().element;
					if(element instanceof Element_Camera){
						Element_Camera cameraLayer = (Element_Camera) element;
						
						getListOfLayersDoLayer(cameraLayer.getLayer(), 0, null);
						defaultShowAllLayers = false;
						
					}
				}
				
			}
			
			
			if(defaultShowAllLayers == true){
				if(engine.getCurrentSelectedTimeline() != null){
					int l = engine.getCurrentSelectedTimeline().layers.size();
					for(int i=0;i<l;i++){
						getListOfLayersDoLayer(engine.getCurrentSelectedTimeline().layers.get(i), 0, null);
					}
				}
			}
			
			
		}
		return listOfLayers;
	}
	private void getListOfLayersDoLayer(TimelineLayer layer, int depth, TimelineLayer parentLayer){
		listOfLayers.add(new TimelineLayerButton(layer, listOfLayers.size(), depth, parentLayer));
		if(layer.showChildren == false) return;
		if(layer.type == TimelineLayerType.FOLDER || layer.type == TimelineLayerType.CAMERA){
			int l = layer.children.size();
			for(int i=0;i<l;i++){
				getListOfLayersDoLayer(layer.children.get(i), depth+1, layer);
			}
			
		}
	}
	public void repaintNamesAndFrames(){
		frames.repaint();
		names.repaint();
		UpdateTimelineScrollbars();
	}
}
